﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Summary description for BookAdapter
/// </summary>
public class BookAdapter
{
    public const int SEARCH_TYPE_ALL = 1;
    public const int SEARCH_TYPE_NEW = 2;
    public const int SEARCH_TYPE_HOT = 3;
    public const int SEARCH_TYPE_MYBOOK = 4;

    public BookAdapter()
    {
        //
        // TODO: Add constructor logic here
        //
    }

    /// <summary></summary>
    /// 
    /// 
    /// 
    /// 
    public List<BookEntity> getListBook(long categoryID, UserEntity user)
    {
        List<BookEntity> books = new List<BookEntity>();
        BookContextDataContext bookContext = new BookContextDataContext();
        try
        {
            List<Book> list = null;
            if (user.RoleID == 1)
            {
                list = bookContext.Books.Where(b => b.CategoryID == categoryID).ToList();
            }
            else
            {
                list = bookContext.Books.Where(b => b.CategoryID == categoryID && b.Author == user.Account).ToList();
            }
            foreach (Book book in list)
            {
                books.Add(new BookEntity(book));

            }
            return books;
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// Get list book by categoryId And platformID 
    /// </summary>
    /// <param name="categoryID"></param>
    /// <param name="platformID"></param>
    public List<BookEntity> getListBook(long categoryID, long platformID, UserEntity user)
    {
        List<BookEntity> books = new List<BookEntity>();
        BookContextDataContext bookContext = new BookContextDataContext();
        try
        {

            if (user.RoleID == 1)
            {
                var list = from b in bookContext.Books
                           join c in bookContext.Categories on b.CategoryID equals c.ID
                           join cd in bookContext.CategoryDetails on c.ID equals cd.CategoryID
                           where cd.PlatformID == platformID && cd.CategoryID == categoryID
                           select b;
                foreach (Book book in list)
                {
                    books.Add(new BookEntity(book));
                }
            }
            else
            {
                var list = from b in bookContext.Books
                           join c in bookContext.Categories on b.CategoryID equals c.ID
                           join cd in bookContext.CategoryDetails on c.ID equals cd.CategoryID
                           where cd.PlatformID == platformID && cd.CategoryID == categoryID && b.Author == user.Account
                           select b;
                foreach (Book book in list)
                {
                    books.Add(new BookEntity(book));
                }
            }

            return books;
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// Get list book by categoryId And list bookDetail 
    /// </summary>
    /// <param name="categoryID"></param>
    /// <param name="details">list bookDetail </param>
    public List<BookEntity> getListBook(long categoryID, List<BookDetailEntity> details, UserEntity user)
    {
        List<BookEntity> books = new List<BookEntity>();
        BookContextDataContext bookContext = new BookContextDataContext();
        try
        {
            List<Book> list = null;
            if (user.RoleID == 1)
            {
                list = bookContext.Books.Where(b => b.CategoryID == categoryID).ToList();
            }
            else
            {
                list = bookContext.Books.Where(b => b.CategoryID == categoryID && b.Author == user.Account).ToList();
            }

            BookEntity bookentity;
            foreach (Book book in list)
            {
                bookentity = new BookEntity(book);
                bool result = true;
                foreach (BookDetailEntity item in details)
                {
                    var num = bookentity.Details.Where(d => d.PlatformID == item.PlatformID).ToList().Count();
                    if (num <= 0)
                    {
                        result = false;
                    }
                }
                if (result == true)
                    books.Add(bookentity);
            }
            return books;
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// Filter Book by key word nameBook
    /// </summary>
    public List<BookEntity> searchBook(string name, UserEntity currentUser)
    {
        List<BookEntity> books = new List<BookEntity>();
        BookContextDataContext bookContext = new BookContextDataContext();
        try
        {

            if (currentUser.RoleID == 1)
            {
                var list = from b in bookContext.Books
                           where b.Name.Contains(name)
                           select b;
                foreach (Book book in list)
                {
                    books.Add(new BookEntity(book));
                }
            }
            else
            {
                var list = from b in bookContext.Books
                           where b.Name.Contains(name) && b.Author == currentUser.Account
                           select b;
                foreach (Book book in list)
                {
                    books.Add(new BookEntity(book));
                }
            }

            return books;
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// Get Book by bookID
    /// </summary>
    public List<BookEntity> getBook(long bookID)
    {
        List<BookEntity> books = new List<BookEntity>();
        BookContextDataContext bookContext = new BookContextDataContext();
        try
        {
            List<Book> list = bookContext.Books.Where(b => b.ID == bookID).ToList();
            foreach (Book book in list)
            {
                books.Add(new BookEntity(book));

            }
            return books;
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// Create Book
    /// </summary>
    /// <param name="newbook entity"></param>
    /// <returns></returns>
    public long CreateBook(BookEntity newbook)
    {
        BookContextDataContext context = new BookContextDataContext();
        try
        {
            //Create new book
            Book book = new Book();
            book.Name = newbook.Name;
            book.Description = newbook.Description;
            book.Link = newbook.Link;
            book.Image = newbook.Image;
            book.CategoryID = newbook.CategoryID;
            book.Active = false;
            book.Author = newbook.Author;
            book.Type = newbook.Type;
            book.NumberOfDownload = 0;
            book.DateUpload = newbook.DateUpload;
            book.UploadBy = newbook.UploadBy;

            context.Books.InsertOnSubmit(book);
            context.SubmitChanges();

            //Create Book detail
            foreach (BookDetailEntity content in newbook.Details)
            {
                context = new BookContextDataContext();

                BookDetail bookdetail = new BookDetail();
                bookdetail.BookID = book.ID;
                bookdetail.PlatformID = content.PlatformID;

                context.BookDetails.InsertOnSubmit(bookdetail);
                context.SubmitChanges();
            }
            return book.ID;
        }
        catch
        {
            return 0;
        }
    }

    /// <summary>
    /// Update Book 
    /// </summary>
    /// <param name="newbook entity"></param>
    /// <returns></returns> 
    public long UpdateItem(BookEntity newbook)
    {
        BookContextDataContext context = new BookContextDataContext();
        try
        {
            Book book = context.Books.SingleOrDefault(t => t.ID == newbook.ID);
            if (book != null)
            {

                book.Name = newbook.Name;
                if (newbook.Image != null)
                {
                    book.Image = newbook.Image;
                }
                if (newbook.Link != null)
                {
                    book.Link = newbook.Link;
                }
                book.DateUpload = newbook.DateUpload;
                book.Description = newbook.Description;

                context.SubmitChanges();



                //Update BookDetail
                foreach (BookDetailEntity content in newbook.Details)
                {
                    context = new BookContextDataContext();

                    BookDetail bookdetail =
                        context.BookDetails.Where(t => t.BookID == content.BookID && t.PlatformID == content.PlatformID)
                            .FirstOrDefault();

                    if (bookdetail == null)
                    {
                        bookdetail = new BookDetail();
                        bookdetail.BookID = content.BookID;
                        bookdetail.PlatformID = content.PlatformID;
                        context.BookDetails.InsertOnSubmit(bookdetail);
                        context.SubmitChanges();
                    }
                }


                List<BookDetail> list = context.BookDetails.Where(b => b.BookID == newbook.ID).ToList();
                foreach (BookDetail content in list)
                {

                    BookDetailEntity bookdetail =
                        newbook.Details.Where(t => t.BookID == content.BookID && t.PlatformID == content.PlatformID).
                            FirstOrDefault();
                    if (bookdetail == null)
                    {

                        context.BookDetails.DeleteOnSubmit(content);
                        context.SubmitChanges();
                    }
                }

                return book.ID;
            }

        }
        catch
        {
        }
        return 0;
    }

    /// <summary>
    /// Delete Book by bookID
    /// </summary>
    /// <param name="BookID"></param>
    /// <returns></returns> 
    public bool DeleteBook(long BookID)
    {
        BookContextDataContext context = new BookContextDataContext();
        try
        {
            //delete conten
            List<BookDetail> listContent = context.BookDetails.Where(t => t.BookID == BookID).ToList();
            context.BookDetails.DeleteAllOnSubmit(listContent);

            //delete item
            Book item = context.Books.SingleOrDefault(t => t.ID == BookID);
            context.Books.DeleteOnSubmit(item);
            context.SubmitChanges();

            return true;
        }
        catch
        {
        }
        return false;
    }

    /// <summary>
    /// Active book 
    /// </summary>
    /// <param name="newbook entity"></param>
    /// <returns></returns> 
    public bool ActiveBook(long bookId, bool active)
    {
        BookContextDataContext context = new BookContextDataContext();
        try
        {
            Book book = context.Books.SingleOrDefault(t => t.ID == bookId);
            if (book != null)
            {
                book.Active = active;

                context.SubmitChanges();
            }
            return true;
        }
        catch
        {
        }
        return false;
    }

    /// <summary>
    /// Get Book by bookID
    /// </summary>   

    public List<BookEntity> getBookByDate(UserEntity currentUser, string day, string month, string year)
    {
        List<BookEntity> books = new List<BookEntity>();
        BookContextDataContext bookContext = new BookContextDataContext();
        try
        {
            var list = from b in bookContext.Books
                       where b.DateUpload.Value.Day.ToString() == day &&
                             b.DateUpload.Value.Month.ToString() == month &&
                             b.DateUpload.Value.Year.ToString() == year && b.Author == currentUser.Account &&
                             b.Active == false
                       select b;
            foreach (Book book in list)
            {
                books.Add(new BookEntity(book));

            }
            return books;
        }
        catch
        {
            return null;
        }
    }

    /// <summary></summary>
    /// 
    /// 
    /// 
    /// 
    public List<BookEntity2> GetBook(long categoryId, int page, int pageNumber, int type, string account)
    {
        int number = (page - 1)*pageNumber;
        var books = new List<BookEntity2>();
        var bookContext = new BookContextDataContext();

        switch (type)
        {
            case SEARCH_TYPE_ALL:
                var list = (from b in bookContext.Books
                            join u in bookContext.Users on b.UploadBy equals u.Account
                            join r in bookContext.Rates on b.ID equals r.BookId
                            select
                                new
                                    {
                                        b.ID,
                                        b.Name,
                                        b.NumberOfDownload,
                                        r.OneStar,
                                        r.TwoStar,
                                        r.ThreeStar,
                                        r.FourStar,
                                        r.FiveStar,
                                        u.Token,
                                        b.Description,
                                        b.Author,
                                        b.Image
                                    }).Skip(number).Take(pageNumber).ToList();

                foreach (var book in list)
                {
                    var entity2 = new BookEntity2();
                    entity2.Id = book.ID;
                    entity2.Name = book.Name;
                    entity2.NumberOfDownload = book.NumberOfDownload;
                    entity2.OneStar = book.OneStar;
                    entity2.TwoStar = book.TwoStar;
                    entity2.ThreeStar = book.ThreeStar;
                    entity2.FourStar = book.FourStar;
                    entity2.FiveStar = book.FiveStar;
                    entity2.Author = book.Author;
                    entity2.Description = book.Description;
                    entity2.Image = book.Image;
                    entity2.Token = book.Token;
                    books.Add(entity2);
                }
                break;
            case SEARCH_TYPE_NEW:
                var list1 = (from b in bookContext.Books
                             join u in bookContext.Users on b.UploadBy equals u.Account
                             join r in bookContext.Rates on b.ID equals r.BookId
                             select
                                 new
                                     {
                                         b.ID,
                                         b.Name,
                                         b.NumberOfDownload,
                                         r.OneStar,
                                         r.TwoStar,
                                         r.ThreeStar,
                                         r.FourStar,
                                         r.FiveStar,
                                         u.Token,
                                         b.Description,
                                         b.Author,
                                         b.Image,
                                         b.DateUpload
                                     }).OrderByDescending(x => x.DateUpload).Skip(number).Take(pageNumber).ToList();

                foreach (var book in list1)
                {
                    var entity2 = new BookEntity2();
                    entity2.Id = book.ID;
                    entity2.Name = book.Name;
                    entity2.NumberOfDownload = book.NumberOfDownload;
                    entity2.OneStar = book.OneStar;
                    entity2.TwoStar = book.TwoStar;
                    entity2.ThreeStar = book.ThreeStar;
                    entity2.FourStar = book.FourStar;
                    entity2.FiveStar = book.FiveStar;
                    entity2.Author = book.Author;
                    entity2.Description = book.Description;
                    entity2.Image = book.Image;
                    entity2.Token = book.Token;
                    books.Add(entity2);

                }
                break;
            case SEARCH_TYPE_HOT:
                var list2 = (from b in bookContext.Books
                             join u in bookContext.Users on b.UploadBy equals u.Account
                             join r in bookContext.Rates on b.ID equals r.BookId
                             select
                                 new
                                 {
                                     b.ID,
                                     b.Name,
                                     b.NumberOfDownload,
                                     r.OneStar,
                                     r.TwoStar,
                                     r.ThreeStar,
                                     r.FourStar,
                                     r.FiveStar,
                                     u.Token,
                                     b.Description,
                                     b.Author,
                                     b.Image,
                                     b.DateUpload
                                 }).OrderByDescending(x => x.DateUpload).Skip(number).Take(pageNumber).ToList();

                foreach (var book in list2)
                {
                    var entity2 = new BookEntity2();
                    entity2.Id = book.ID;
                    entity2.Name = book.Name;
                    entity2.NumberOfDownload = book.NumberOfDownload;
                    entity2.OneStar = book.OneStar;
                    entity2.TwoStar = book.TwoStar;
                    entity2.ThreeStar = book.ThreeStar;
                    entity2.FourStar = book.FourStar;
                    entity2.FiveStar = book.FiveStar;
                    entity2.Author = book.Author;
                    entity2.Description = book.Description;
                    entity2.Image = book.Image;
                    entity2.Token = book.Token;
                    books.Add(entity2);

                }
                break;
            case SEARCH_TYPE_MYBOOK:
                var list3 = (from b in bookContext.Books
                             join u in bookContext.Users on b.UploadBy equals u.Account
                             join r in bookContext.Rates on b.ID equals r.BookId
                             where u.Account==account
                             select
                                 new
                                 {
                                     b.ID,
                                     b.Name,
                                     b.NumberOfDownload,
                                     r.OneStar,
                                     r.TwoStar,
                                     r.ThreeStar,
                                     r.FourStar,
                                     r.FiveStar,
                                     u.Token,
                                     b.Description,
                                     b.Author,
                                     b.Image,
                                     b.DateUpload
                                 }).Skip(number).Take(pageNumber).ToList();

                foreach (var book in list3)
                {
                    var entity2 = new BookEntity2();
                    entity2.Id = book.ID;
                    entity2.Name = book.Name;
                    entity2.NumberOfDownload = book.NumberOfDownload;
                    entity2.OneStar = book.OneStar;
                    entity2.TwoStar = book.TwoStar;
                    entity2.ThreeStar = book.ThreeStar;
                    entity2.FourStar = book.FourStar;
                    entity2.FiveStar = book.FiveStar;
                    entity2.Author = book.Author;
                    entity2.Description = book.Description;
                    entity2.Image = book.Image;
                    entity2.Token = book.Token;
                    books.Add(entity2);
                }
                break;
        }
        return books;
    }
    
    public List<BookEntity2> SearchBook(string keyWord, int page, int pageNumber)
    {
        int number = (page - 1) * pageNumber;
        var books = new List<BookEntity2>();
        var bookContext = new BookContextDataContext();

        var list = (from b in bookContext.Books
                    join u in bookContext.Users on b.UploadBy equals u.Account
                    join r in bookContext.Rates on b.ID equals r.BookId
                    where b.Name.Contains(keyWord)
                    select
                        new
                        {
                            b.ID,
                            b.Name,
                            b.NumberOfDownload,
                            r.OneStar,
                            r.TwoStar,
                            r.ThreeStar,
                            r.FourStar,
                            r.FiveStar,
                            u.Token,
                            b.Description,
                            b.Author,
                            b.Image,
                            b.DateUpload
                        }).Skip(number).Take(pageNumber).ToList();

        foreach (var book in list)
        {
            var entity2 = new BookEntity2();
            entity2.Id = book.ID;
            entity2.Name = book.Name;
            entity2.NumberOfDownload = book.NumberOfDownload;
            entity2.OneStar = book.OneStar;
            entity2.TwoStar = book.TwoStar;
            entity2.ThreeStar = book.ThreeStar;
            entity2.FourStar = book.FourStar;
            entity2.FiveStar = book.FiveStar;
            entity2.Author = book.Author;
            entity2.Description = book.Description;
            entity2.Image = book.Image;
            entity2.Token = book.Token;
            books.Add(entity2);
        }
        return books;
    }

    public string GetLinkBook(long bookId)
    {
        var context=new BookContextDataContext();
        Book book = context.Books.SingleOrDefault(t => t.ID == bookId);
        if (book != null) 
            return book.Link;
        return "";
    }

    public bool RateBook(int numberRate,long bookId)
    {
        var context = new BookContextDataContext();
        Rate rate = context.Rates.SingleOrDefault((r=>r.BookId==bookId));
        if (rate == null)
            return false;
        if (numberRate==1)
        {
            rate.OneStar += 1;
        }
        if (numberRate==2)
        {
            rate.TwoStar += 1;
        }
        if (numberRate==3)
        {
            rate.ThreeStar += 1;
        }
        if (numberRate==4)
        {
            rate.FourStar += 1;
        }
        if (numberRate==5)
        {
            rate.FiveStar += 1;
        }
        context.SubmitChanges();
        return true;
    }
/*
/// <summary></summary>
    /// 
    /// 
    /// 
    /// 
    public List<BookEntity> getListBookByAccount(long categoryID, string account, int page)
    {
        int number = (1 - 1) * 40+1;
        List<BookEntity> books = new List<BookEntity>();
        BookContextDataContext bookContext = new BookContextDataContext();
        try
        {
            List<Book> list = null;           
            list = bookContext.Books.Where(b => b.CategoryID == 1).Skip(number).Take(40).ToList();
           
            foreach (Book book in list)
            {
                books.Add(new BookEntity(book));

            }
            return books;
        }
        catch
        {
            return null;
        }
    }
*/
}
